package com.letv.core.download.image;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.content.Context;
import android.graphics.Bitmap;

import com.letv.core.download.image.DiskLruCache.Snapshot;
import com.letv.core.download.image.ImageDownloader.BitmapConfig;
import com.letv.core.utils.FileUtils;
import com.letv.core.utils.LetvThumbnailUtils;
import com.letv.core.utils.LogInfo;
import com.letv.core.utils.MD5;
import com.media.NativeThumbnail;

/**
 * 磁盘缓存
 * 
 * @author zhuqiao
 *
 */
public class DiscCache {
    private static final int MAX = 50 * 1024 * 1024;

    private Context mContext;
    private final DiskLruCache mDiskLruCache;

    public DiscCache(Context context) {
        mContext = context;
        String path = FileUtils.getBitmapCachePath(mContext);
        File cacheDir = new File(path);
        LogInfo.log("zhuqiao", "pic cache:" + cacheDir.getAbsolutePath());
        if (!cacheDir.exists()) {
            cacheDir.mkdirs();
        }
        mDiskLruCache = DiskLruCache.open(cacheDir, 1, 1, MAX);
    }

    /**
     * 增加获取缩略图Bitmap
     * 
     * @param url
     * @param config
     * @return
     */
    public Bitmap getThumbnailBitmap(String url, BitmapConfig config) {
        Bitmap bitmap = getBitmapFromDisk(url, config);
        LogInfo.log("DiscCache", "getThumbnailBitmap local bitmap : " + bitmap);
        try {
            bitmap = LetvThumbnailUtils.getThumbnailBitmap(url);
            LogInfo.log("DiscCache", "getThumbnailBitmap bitmap : " + bitmap);
            if (bitmap == null) {
                NativeThumbnail nativeThumbnail = new NativeThumbnail(url);
                bitmap = nativeThumbnail.getVideoThumbnail(96, 96, 10);
            }

            if (bitmap != null) {
                DiskLruCache.Editor editor = mDiskLruCache.edit(MD5.MD5Encode(url));
                if (editor != null) {
                    OutputStream outputStream = editor.newOutputStream(0);
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                    editor.commit();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    /**
     * 从网络获取bitmap
     * 
     * @param url
     * @param config
     * @return
     */
    public Bitmap getBitmapFromNetwork(String url, BitmapConfig config) {
        try {
            DiskLruCache.Editor editor = mDiskLruCache.edit(MD5.MD5Encode(url));
            if (editor == null) {
                return getBitmapFromNetworkWithoutLru(url, config);
            }

            OutputStream outputStream = editor.newOutputStream(0);
            if (DownloaderFromHttp.download(url, outputStream)) {
                editor.commit();
            } else {
                editor.abort();
            }
            return getBitmapFromDisk(url, config);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 从网络获取bitmap
     * 
     * @param url
     * @param config
     * @return
     */
    public Bitmap getBitmapFromNetworkWithoutLru(String url, BitmapConfig config) {
        byte[] data = DownloaderFromHttp.download(url);
        if (data != null && data.length > 0) {
            ImgFileManager.saveImage(mContext, url, data);

            if (config == null) {
                return BitmapDecoder.decodeSampledBitmapFromByteArray(data, 0, data.length);
            } else {
                return BitmapDecoder
                        .decodeSampledBitmapFromByteArray(data, 0, data.length, config.width, config.height);
            }

        }

        return null;
    }

    /**
     * 从磁盘获取bitmap
     * 
     * @param key
     * @return
     */
    public Bitmap getBitmapFromDisk(String key, BitmapConfig config) {
        Snapshot snapshot = null;
        try {
            snapshot = mDiskLruCache.get(MD5.MD5Encode(key));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        if (snapshot == null) {
            return getBitmapFromDiskWithoutLru(key, config);
        }

        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;

        try {
            fis = (FileInputStream) snapshot.getInputStream(0);
            if (fis == null) {
                return getBitmapFromDiskWithoutLru(key, config);
            }

            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            byte[] data = bos.toByteArray();

            if (data == null)
                return null;

            if (config == null) {
                return BitmapDecoder.decodeSampledBitmapFromByteArray(data, 0, data.length);
            } else {
                return BitmapDecoder
                        .decodeSampledBitmapFromByteArray(data, 0, data.length, config.width, config.height);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null)
                    bos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    /**
     * 从磁盘获取bitmap
     * 
     * @param key
     * @return
     */
    public Bitmap getBitmapFromDiskWithoutLru(String key, BitmapConfig config) {
        byte[] data = ImgFileManager.getImage(mContext, key);
        if (data == null)
            return null;

        if (config == null) {
            return BitmapDecoder.decodeSampledBitmapFromByteArray(data, 0, data.length);
        } else {
            return BitmapDecoder.decodeSampledBitmapFromByteArray(data, 0, data.length, config.width, config.height);
        }
    }

    /**
     * 将缓存记录同步到journal文件中。
     */
    public void fluchCache() {
        if (mDiskLruCache != null) {
            try {
                mDiskLruCache.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void closeCache() {
        if (mDiskLruCache != null) {
            try {
                mDiskLruCache.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
